﻿using Newtonsoft.Json;
using SideMan.Models;
using SideMan.Views;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace SideMan.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        #region Properties
        Window _win;
        string _AppTitle;
        /// <summary>
        /// 应用标题
        /// </summary>
        public string AppTitle { get => _AppTitle; set => SetProperty(ref _AppTitle, value); }
        int _appWidth;
        public int AppWidth { get => _appWidth; set => SetProperty(ref _appWidth, value); }

        ObservableCollection<NoteViewModel> _notes;
        public ObservableCollection<NoteViewModel> NoteViewModels { get => _notes; set => SetProperty(ref _notes, value); }

        // The current folder's Title
        string _folderTitle;
        public string FolderTitle { get => _folderTitle; set => SetProperty(ref _folderTitle, value); }
        string _SearchText;
        public string SearchText { get => _SearchText; set => SetProperty(ref _SearchText, value); }

        private bool isContextMenuOpen;

        public bool IsContextMenuOpen { get => isContextMenuOpen; set => SetProperty(ref isContextMenuOpen, value); }
        private UIElement contextMenuPlacementTarget;
        public UIElement ContextMenuPlacementTarget { get => contextMenuPlacementTarget; set => SetProperty(ref contextMenuPlacementTarget, value); }
        private ScrollViewer scrollViewer;
        public ScrollViewer ScrollViewer { get => scrollViewer; set => SetProperty(ref scrollViewer, value); }
        #endregion

        #region ctor
        public MainViewModel(Window window)
        {
            this._win = window;

            init();
        }


        #endregion

        #region Methods
        private void init()
        {
            Log.Verbose("init application");
            AppTitle = $"{Constants.APP_NAME}";
            FolderTitle = "Index";
            SearchText = "";
            IsContextMenuOpen = false;
            AppWidth = AppHelper.Inst.AppWidth;

            NoteViewModels = new ObservableCollection<NoteViewModel>();


            NoteViewModel newNote = new NoteViewModel { Title = "New Note1", ID = "0" };
            NoteViewModels.Add(newNote);

            loadData();

            // Subscribe to the application exit event
            Application.Current.Exit += OnApplicationExit;
        }


        private void OnApplicationExit(object sender, ExitEventArgs e)
        {
            // Clean up resources or perform any necessary tasks before exiting
            // This method will be called when the application is shutting down
            Log.Debug("Application is exiting. Performing cleanup...");
            TextData[] textDatas = new TextData[NoteViewModels.Count];

            for (int i = 0; i < NoteViewModels.Count; i++)
            {
                var note = NoteViewModels[i];
                var dat = NoteHelper.ToJson(note);
                dat.No = i;
                textDatas[i] = dat;
            }

            var dataPath = Path.Combine(Environment.CurrentDirectory, Constants.ASSETS_FOLDER);

            NoteHelper.Save(textDatas, dataPath);
        }
        private void loadData()
        {
            String folderName = "data";
            String dataFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, folderName);
            if (!Directory.Exists(dataFolderPath))
            {
                Directory.CreateDirectory(dataFolderPath);
            }

            // Get all files with the extension "json" in the "data" folder
            string[] jsonFiles = Directory.GetFiles(dataFolderPath, "*.json");
            List<TextData> textDatas = new List<TextData>();
            TextData mainTextData = new TextData();

            foreach (var file in jsonFiles)
            {
                var textData = loadJsonFile(file);
                textDatas.Add(textData);
            }

            var allDatas = textDatas.ToArray();

            Array.Sort(allDatas, (item1, item2) => item1.No.CompareTo(item2.No));

            loadAllFile(allDatas);
        }
        private TextData loadJsonFile(string jsonFile)
        {
            // Read the content of the JSON file
            string jsonContent = File.ReadAllText(jsonFile);

            // Deserialize the JSON content into a C# object
            TextData jsonData = JsonConvert.DeserializeObject<TextData>(jsonContent);

            //// Use LINQ to query the deserialized object
            //var queryResult = from item in jsonData.Items
            //                  where item.SomeProperty == "SomeValue"
            //                  select item;

            return jsonData;
        }
        private void loadAllFile(TextData[] textDatas)
        {
            NoteViewModels = new ObservableCollection<NoteViewModel>();
            for (int i = 0; i < textDatas.Length; i++)
            {
                var dat = textDatas[i];

                NoteViewModel note = NoteHelper.FromData(dat);

                NoteViewModels.Add(note);
            }
        }

        private void Note_saveEventHandler(object sender, EventArgs e)
        {
            Log.Debug("save note");
            NoteEventArgs nea = e as NoteEventArgs;
            if (null != nea && null != nea.NoteViewModel)
            {
                var vm = nea.NoteViewModel;
                var found = NoteViewModels.FirstOrDefault(note => note.ID == vm.ID);
                if (null == found)
                {
                    throw new ApplicationException("未找到资源");
                }

                int idx = NoteViewModels.IndexOf(found);
                NoteViewModels[idx] = vm;
            }
        }

        private void newNoteClicked(object obj)
        {
            Log.Debug("New Note");

            NoteViewModel newNote = new NoteViewModel { Title = "New Note" };
            NoteViewModels.Add(newNote);
        }

        private void showMenu(UIElement target)
        {
            IsContextMenuOpen = true;
            ContextMenuPlacementTarget = target;
        }
        private void newEmptyNote()
        {
            var note = new NoteViewModel();
            note.ID = DateTime.Now.ToString("yyyyMMddHHmmssfff");

            //Paragraph paragraph = new Paragraph(new Run("Text Note"));
            note.RichTextBoxContent = "UEsDBBQAAAAIAPtUhVfMgXa2iQIAAMkIAAASABwAWGFtbC9Eb2N1bWVudC54YW1sIKIYACigFAAAAAAAAAAAAAAAAAAAAAAAAAAAAK2WUW /aMBDHv0rkPUPiQOmIAAm1Za1Gq6npVm1v13BNrDl2ZDst9NPPhrQNI9R7GG+2f/e/89/xmUmKmWFSBOuSCz0lhTFVEoY6K7AE3S9ZpqSWj6afyTJ8ZuJxHcZRNArXUPKwUqhRGHACxCkkuoIMp2S7oJ6QBHe4NnPOclFacEqW+GhIsGQCL5HlhZ2Z10aS4EpfbqoCxVbqQsADx9WULIBr3AlzEPmUoOjVmgQLLp/PmdpVvhO9k7dOjwQ3dfmAKq0ftGGmdkD/rOamVpjKWrniXEmdXHtgC9NNnM0nhVlAyfhmSq5fHQl+gt1D8P1qt56aDbfiN1KVwHdT980W23OpUWiy4q9J9mJDaexGCnMla2F3/2mxiLY/6+KmkrmCqtj0UwNiBWq1ZDm46uyZ3aka95gzq2k3WQP/iDpnOrPF2M2C2rTAxvUWecm0kYple3qH2FwIufsY5tygsofpuOhIaW3moLb3jNaRsjPbVxvN3EdxuH2omAGe2m9xCxzGnoHGFIVmhj3h0QzuSG0dLEvRUB8Q+4CBDxj6gBMfMPIBpz7gsw8Ye42KvITXS+o1k3rdpF47qddP6jWUeh2lXkup19O409OFgqYBvvaSdjgHXeDqFyrZFXsNxjV4427YF4X4uwu6AG3mmoG4WFeozNF78gOUhYzuLKS5jN2Ltgmjsjd1v3ceAq0XpAN6q/OerUzRnemNWdqHpIa8O91rc02fnXsfNK8jwNuh7TfA2eQbKNgys8ltLWZxFA96lPbiz0E0SAajZDCehG7Brbbeu5eilwkyC4LgfXk2Go0pbcZhS/jjHOMkGnly/JvwYeh+puEgiU7/n9owORk7tdNhp1rY/H+Z/QFQSwMECgAAAAAA+1SFV5VqFDIMAQAADAEAAAsAHABfcmVscy8ucmVscyCiGAAooBQAAAAAAAAAAAAAAAAAAAAAAAAAAADvu788P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI/PjxSZWxhdGlvbnNoaXBzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvcGFja2FnZS8yMDA2L3JlbGF0aW9uc2hpcHMiPjxSZWxhdGlvbnNoaXAgVHlwZT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cGYvMjAwNS8xMC94YW1sL2VudHJ5IiBUYXJnZXQ9Ii9YYW1sL0RvY3VtZW50LnhhbWwiIElkPSJSZjkxNzM4YWEyNDMyNDMwMiIgLz48L1JlbGF0aW9uc2hpcHM+UEsDBAoAAAAAAPtUhVc1zfV3KgEAACoBAAATABwAW0NvbnRlbnRfVHlwZXNdLnhtbCCiGAAooBQAAAAAAAAAAAAAAAAAAAAAAAAAAADvu788P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI/PjxUeXBlcyB4bWxucz0iaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3BhY2thZ2UvMjAwNi9jb250ZW50LXR5cGVzIj48RGVmYXVsdCBFeHRlbnNpb249InhhbWwiIENvbnRlbnRUeXBlPSJhcHBsaWNhdGlvbi92bmQubXMtd3BmLnhhbWwreG1sIiAvPjxEZWZhdWx0IEV4dGVuc2lvbj0icmVscyIgQ29udGVudFR5cGU9ImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1wYWNrYWdlLnJlbGF0aW9uc2hpcHMreG1sIiAvPjwvVHlwZXM+UEsBAi0AFAAAAAgA+1SFV8yBdraJAgAAyQgAABIAAAAAAAAAAAAAAAAAAAAAAFhhbWwvRG9jdW1lbnQueGFtbFBLAQItAAoAAAAAAPtUhVeVahQyDAEAAAwBAAALAAAAAAAAAAAAAAAAANUCAABfcmVscy8ucmVsc1BLAQItAAoAAAAAAPtUhVc1zfV3KgEAACoBAAATAAAAAAAAAAAAAAAAACYEAABbQ29udGVudF9UeXBlc10ueG1sUEsFBgAAAAADAAMAugAAAJ0FAAAAAA==";// new FlowDocument(paragraph);

            NoteViewModels.Add(note);
        }
        private void addClicked(object obj)
        {
            Log.Debug("Add clicked");
            newEmptyNote();
            scrollToEndClicked(null);
        }

        private void removeClicked(NoteViewModel note)
        {
            Log.Debug("Remove clicked");
            var path = Path.Combine(Environment.CurrentDirectory, Constants.ASSETS_FOLDER, $"{note.ID}.json");
            if (File.Exists(path))
            {
                File.Delete(path);
            }
            NoteViewModels?.Remove(note);
        }
        private void searchClicked(object obj)
        {
            Log.Debug("Search clicked");
        }
        private void gobackClicked(object obj)
        {
            Log.Debug("Goback clicked");
        }
        private void settingClicked(object obj)
        {
            throw new NotImplementedException();
        }
        private void pasteClicked(object obj)
        {
            Log.Debug("paste clicked");
        }
        private void scrollToEndClicked(object obj)
        {
            ScrollViewer?.ScrollToEnd();
        }

        public void Window_Loaded(object sender, RoutedEventArgs e)
        {
            ScrollViewer?.ScrollToEnd();
        }
        private void openClicked(object obj)
        {
            NoteViewModel noteViewModel = obj as NoteViewModel;
            NoteWindow noteWindow = new NoteWindow(noteViewModel);

            noteViewModel.saveEventHandler += Note_saveEventHandler;
            noteWindow.Show();
        }


        #endregion

        #region Commands
        RelayCommand _newCommand, _addCommand, _searchCommand, _gobackCommand, _settingCommand, _pasteCommand, _scrollToEndCommand, _openCommand;
        RelayCommand<NoteViewModel> _removeCommand;
        public RelayCommand NewCommand => _newCommand ?? (_newCommand = new RelayCommand(newNoteClicked));
        public RelayCommand AddCommand => _addCommand ?? (_addCommand = new RelayCommand(addClicked));
        public RelayCommand<NoteViewModel> RemoveCommand => _removeCommand ?? (_removeCommand = new RelayCommand<NoteViewModel>(removeClicked));
        public RelayCommand SearchCommand => _searchCommand ?? (_searchCommand = new RelayCommand(searchClicked));
        public RelayCommand GoBackCommand => _gobackCommand ?? (_gobackCommand = new RelayCommand(gobackClicked));
        public RelayCommand SettingCommand => _settingCommand ?? (_settingCommand = new RelayCommand(settingClicked));
        public RelayCommand ScrollToEndCommand => _scrollToEndCommand ?? (_scrollToEndCommand = new RelayCommand(scrollToEndClicked));
        public RelayCommand OpenCommand => _openCommand ?? (_openCommand = new RelayCommand(openClicked));




        #endregion
    }
}
